package com.sunny.ihealth.ui.activity;

import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.utils.DistanceUtil;
import com.google.gson.Gson;
import com.sunny.ihealth.BaseActivity;
import com.sunny.ihealth.R;
import com.sunny.ihealth.data.LocalData;
import com.sunny.ihealth.entity.app.Msg;
import com.sunny.ihealth.entity.app.Point;
import com.sunny.ihealth.entity.eventbus.SportDataChangeEvent;
import com.sunny.ihealth.ui.view.SomeDialogs;
import com.sunny.ihealth.utils.TimeUtils;

import org.greenrobot.eventbus.EventBus;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.bmob.newim.BmobIM;
import cn.bmob.newim.bean.BmobIMConversation;
import cn.bmob.newim.bean.BmobIMMessage;
import cn.bmob.newim.bean.BmobIMTextMessage;
import cn.bmob.newim.bean.BmobIMUserInfo;
import cn.bmob.newim.core.BmobIMClient;
import cn.bmob.newim.event.MessageEvent;
import cn.bmob.newim.listener.ConversationListener;
import cn.bmob.newim.listener.MessageListHandler;
import cn.bmob.newim.listener.MessageSendListener;
import cn.bmob.v3.exception.BmobException;

public class StartRunActivity extends BaseActivity implements View.OnClickListener, MessageListHandler {

    private static final String TAG = "StartRunActivity";
    private static final float MAP_ZOOM = 18;

    private Vibrator vibrator;

    private BmobIMConversation conversation;
    private BmobIMUserInfo imUserInfo;

    public LocationClient mLocationClient = null;
    public BDLocationListener myListener = new MyLocationListener(this);

    private boolean isStart = false;
    //是否在看ta
    private boolean viewTA = false;
    //朋友是否开始跑步
    private boolean friendIsRun = false;
    //是否只有我（单机模式）
    private boolean isOnlyMe = true;
    //标志是否为第一次定位
    private boolean isFirstIn = true;
    //开始时间
    private long starTime;
    //距离，米
    private int distance;
    //时间，分钟
    private int runTime;


    private List<LatLng> myTrailLng;
    private List<LatLng> friendTrailLng;

    private BaiduMap mBaiduMap;
    private Button btnStar;  //开始轨迹记录
    private Button btnStop;  //结束轨迹记录
    //看别人
    private Button btnView;
    private TextView tvDistance;
    private TextView tvSpeed;
    private TextView tvTime;
    private Button btnLike, btnSend;
    private ScrollView scrollMessage;
    private TextView tvMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start_run);

        BmobIM.getInstance().addMessageListHandler(this);

        initViews();
        initData();
    }

    @Override
    public void initViews() {
        setToolbar("跑步");
        setEnableBackIcon(true);
        setStatusBarColor();

        MapView mMapView = (MapView) findViewById(R.id.bmapView);
        mMapView.showZoomControls(false);
        mBaiduMap = mMapView.getMap();
        mBaiduMap.setMyLocationEnabled(true);
        btnStar = (Button) findViewById(R.id.btn_star_loc);
        btnStop = (Button) findViewById(R.id.btn_stop_loc);
        tvDistance = (TextView) findViewById(R.id.tv_distance);
        tvSpeed = (TextView) findViewById(R.id.tv_speed);
        tvTime = (TextView) findViewById(R.id.tv_time);
        btnView = (Button) findViewById(R.id.btn_startRun_view);
        btnLike = (Button) findViewById(R.id.btn_startRun_like);
        btnSend = (Button) findViewById(R.id.btn_startRun_talk);
        scrollMessage = (ScrollView) findViewById(R.id.scroll_startRun_message);
        tvMessage = (TextView) findViewById(R.id.tv_startRun_message);


        btnStar.setOnClickListener(this);
        btnStop.setOnClickListener(this);
        btnView.setOnClickListener(this);
        btnLike.setOnClickListener(this);
        btnSend.setOnClickListener(this);


    }

    @Override
    public void initData() {
        if ((imUserInfo = (BmobIMUserInfo) getIntent().getSerializableExtra("data")) == null) {
            //Toast.makeText(StartRunActivity.this, "单机模式", Toast.LENGTH_SHORT).show();
            btnView.setVisibility(View.GONE);
            btnLike.setVisibility(View.GONE);
            btnSend.setVisibility(View.GONE);
            scrollMessage.setVisibility(View.GONE);

            isOnlyMe = true;
        } else {

            appendMessage(true, "等待好友跑步");

            btnLike.setVisibility(View.VISIBLE);
            btnSend.setVisibility(View.VISIBLE);
            scrollMessage.setVisibility(View.VISIBLE);

            BmobIM.getInstance().startPrivateConversation(imUserInfo, false, new ConversationListener() {
                @Override
                public void done(BmobIMConversation c, BmobException e) {
                    if (e != null) {
                        Log.e(TAG, "连接错误:   " + e.getMessage());
                    } else {
                        conversation = BmobIMConversation.obtain(BmobIMClient.getInstance(), c);
                        isOnlyMe = false;
                        Toast.makeText(StartRunActivity.this, "获取会话成功", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }


        mLocationClient = new LocationClient(getApplicationContext());     //声明LocationClient类
        initLocation();
        mLocationClient.registerLocationListener(myListener);           //注册监听函数

        myTrailLng = new ArrayList<>();
        friendTrailLng = new ArrayList<>();

        vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);

    }


    /**
     * 初始定位设置
     */
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可设置定位模式，高精度，低功耗，仅设备
        //Hight_Accuracy高精度、Battery_Saving低功耗、Device_Sensors仅设备(GPS)
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
        int span = 1000;
        option.setScanSpan(span);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setOpenGps(true);//可选，默认false,设置是否使用gps
        option.setLocationNotify(true);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选，默认false，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认杀死
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤gps仿真结果，默认需要
        mLocationClient.setLocOption(option);
    }

    /**
     * 画点方法
     */
    private void makerPoint(LatLng point, int id) {
        BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(id);
        OverlayOptions option = new MarkerOptions().position(point).icon(bitmap);
        mBaiduMap.addOverlay(option);
    }


    /**
     * 画线方法
     */
    private void makeTrail(List<LatLng> points) {

        if (points.size() > 1) {
            //构造对象
            OverlayOptions overlayOptions = new PolylineOptions()
                    .width(15)
                    .dottedLine(false)
                    .points(points)
                    .color(Color.RED);
            //添加到地图
            mBaiduMap.clear();
            makerPoint(points.get(0), R.drawable.star_point);
            mBaiduMap.addOverlay(overlayOptions);

        } else if (points.size() == 1) {
            mBaiduMap.clear();
            makerPoint(points.get(0), R.drawable.star_point);
        }
    }


    /**
     * 判断GPS是否开启
     */
    private boolean isGpsEnable(Context context) {
        LocationManager locationManager = ((LocationManager) context.getSystemService(Context.LOCATION_SERVICE));
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }


    @Override
    public void onClick(View view) {
        int i = view.getId();
        switch (i) {
            case R.id.btn_star_loc:   //开始
                if (isGpsEnable(this)) {
                    btnStar.setVisibility(View.GONE);
                    btnStop.setVisibility(View.VISIBLE);

                    myTrailLng.clear();
                    mLocationClient.start();

                    isStart = true;
                    starTime = Calendar.getInstance().getTimeInMillis();
                    runTime = 0;
                    distance = 0;

                    if (!isOnlyMe) {
                        sendMessage("start_run", null);
                        appendMessage(true, "开始跑步~");
                    }


                } else {
                    Toast.makeText(this, "请先打开GPS ！", Toast.LENGTH_SHORT).show();
                }

                break;
            case R.id.btn_stop_loc:   //结束
                btnStar.setVisibility(View.VISIBLE);
                btnStop.setVisibility(View.GONE);

                isStart = false;

                mLocationClient.stop();

                if (myTrailLng.size() > 8) {
                    getNowSpeed();
                    LocalData.saveDistanceAndTime(getCurrentUser(), distance, runTime);
                    SportDataChangeEvent event = new SportDataChangeEvent();
                    event.setType(SportDataChangeEvent.Type.RUN);
                    EventBus.getDefault().post(event);
                } else {  //  小于8
                    Toast.makeText(this, "距离过短 无法记录", Toast.LENGTH_SHORT).show();
                }

                if (!isOnlyMe) {
                    sendMessage("stop_run", null);
                    appendMessage(true, "结束开步~");
                }

                break;

            case R.id.btn_startRun_view:
                //没有看他
                if (!viewTA) {
                    if (!friendIsRun) {
                        Toast.makeText(StartRunActivity.this, "TA还没有开始跑步...", Toast.LENGTH_SHORT).show();
                        return;
                    } else {
                        if (friendTrailLng.size() <= 0) {
                            Toast.makeText(StartRunActivity.this, "TA还没有轨迹...", Toast.LENGTH_SHORT).show();
                            return;
                        }
                        sendMessage("msg", "正在看你哦~");
                        mBaiduMap.clear();
                        viewTA = true;
                        btnView.setText("看我");
                        makeTrail(friendTrailLng);
                        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(friendTrailLng.get(0), MAP_ZOOM);
                        mBaiduMap.animateMapStatus(msu);
                    }
                } else {
                    mBaiduMap.clear();
                    viewTA = false;
                    btnView.setText("看TA");
                    makeTrail(myTrailLng);
                    if (myTrailLng.size() > 0) {
                        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(myTrailLng.get(0), MAP_ZOOM);
                        mBaiduMap.animateMapStatus(msu);
                    }
                }
                break;

            case R.id.btn_startRun_like:
                sendMessage("msg", "不错哦，赞你一下~");
                appendMessage(true, "赞了" + imUserInfo.getName() + "一下");
                break;
            case R.id.btn_startRun_talk:
                SomeDialogs.inputDialog(this, new SomeDialogs.SubmitListener() {
                    @Override
                    public void onSubmit(String text) {
                        text = text.trim();
                        if (TextUtils.isEmpty(text)) {
                            Toast.makeText(StartRunActivity.this, "先说点什么吧~", Toast.LENGTH_SHORT).show();
                        } else {
                            sendMessage("msg", text);
                            appendMessage(true, text);
                        }
                    }
                }, "", "发送消息", "说点什么吧", "发送", "取消", 50);
        }
    }


    private double getNowDistance() {
        double distance = 0.0;
        for (int i = 0; i < myTrailLng.size() - 1; i++) {
            distance += DistanceUtil.getDistance(myTrailLng.get(i), myTrailLng.get(i + 1));
        }
        this.distance = (int) distance;
        distance = distance / 1000;
        return distance;
    }

    /**
     * 获取当前数据
     */
    private void getNowSpeed() {
        //分钟
        double time = (Calendar.getInstance().getTimeInMillis() - starTime + 0.0) / (1000 * 60);

        //千米
        double distance = getNowDistance();
        //千米/时
        double speed = distance / (time / 60);

        DecimalFormat df = new DecimalFormat("0.##");
        tvDistance.setText(df.format(distance));
        tvSpeed.setText(df.format(speed));

        int timeInInt = (int) time + 1;
        runTime = timeInInt;
        tvTime.setText(timeInInt + "");
    }


    public class MyLocationListener implements BDLocationListener {
        private Context context;
        private LatLng lastLngLast = new LatLng(0.0, 0.0);
        int updateCount = 0;  //更新数据TextView 频率 （多少点后）

        MyLocationListener(Context context) {
            this.context = context;
        }

        @Override
        public void onReceiveLocation(BDLocation location) {

            //定义Maker坐标点
            LatLng point = new LatLng(location.getLatitude(), location.getLongitude());

            MyLocationData data = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude())
                    .build();
            mBaiduMap.setMyLocationData(data);


            if (isFirstIn) {
                LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(latLng, MAP_ZOOM);
                mBaiduMap.animateMapStatus(msu);
                isFirstIn = false;

                Toast.makeText(context, location.getAddrStr(), Toast.LENGTH_SHORT).show();
            }


            if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                double dis = DistanceUtil.getDistance(point, lastLngLast);  //两点距离
                if (dis > 4.0) {
                    myTrailLng.add(point);
                    updateCount++;
                    if (updateCount > 4) {
                        getNowSpeed();
                        updateCount = 0;
                    }
                    if (!isOnlyMe) {
                        BmobIMTextMessage msg = new BmobIMTextMessage();
                        msg.setContent("point");
                        Map<String, Object> map = new HashMap<>();
                        map.put("latitude", point.latitude);
                        map.put("longitude", point.longitude);
                        msg.setExtraMap(map);
                        conversation.sendMessage(msg, messageSendListener);
                    }
                    if (!viewTA) {
                        makeTrail(myTrailLng);
                    }
                    lastLngLast = point;
                }
            }
        }
    }


    @Override
    public void onMessageReceive(List<MessageEvent> list) {
        BmobIMMessage msg = list.get(0).getMessage();
        switch (msg.getContent()) {
            case "start_run":
                vibrator.vibrate(new long[]{300, 300, 300, 300}, -1);
                friendIsRun = true;
                friendTrailLng.clear();
                appendMessage(false, "开始跑步了");
                break;
            case "stop_run":
                vibrator.vibrate(new long[]{300, 300, 300, 300}, -1);
                friendIsRun = false;
                appendMessage(false, "结束跑步了");
                break;
            case "point":
                Point point = new Gson().fromJson(msg.getExtra(), Point.class);
                LatLng latLng = new LatLng(point.getLatitude(), point.getLongitude());
                friendTrailLng.add(latLng);
                if (viewTA) {
                    makeTrail(friendTrailLng);
                }
                break;
            case "msg":
                vibrator.vibrate(new long[]{300, 300, 300, 300}, -1);
                Msg msg1 = new Gson().fromJson(msg.getExtra(), Msg.class);
                appendMessage(false, msg1.getEx_msg());
                break;
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();
        BmobIM.getInstance().removeMessageListHandler(this);
    }

    private void sendMessage(String content, String message) {
        BmobIMTextMessage msg = new BmobIMTextMessage();
        msg.setContent(content);
        if (message != null) {
            Map<String, Object> map = new HashMap<>();
            map.put("ex_msg", message);
            msg.setExtraMap(map);
        }
        conversation.sendMessage(msg, messageSendListener);
    }

    private static MessageSendListener messageSendListener = new MessageSendListener() {
        @Override
        public void done(BmobIMMessage bmobIMMessage, BmobException e) {
        }
    };


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (isStart && keyCode == KeyEvent.KEYCODE_BACK) {
            returnDialog();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            returnDialog();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


    private void returnDialog() {
        new AlertDialog.Builder(this)
                .setTitle("提示")
                .setMessage("您还没有结束跑步，要退出吗?")
                .setNegativeButton("取消", null)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        btnStop.callOnClick();
                        finish();
                    }
                })
                .create()
                .show();
    }


    private void appendMessage(boolean me, String message) {
        if (me) {
            tvMessage.append("我 " + TimeUtils.getTime(System.currentTimeMillis()) + "\n" + message + "\n");
        } else {
            tvMessage.append(imUserInfo.getName() + " " + TimeUtils.getTime(System.currentTimeMillis()) + "\n" + message + "\n");
        }
        scrollMessage.post(new Runnable() {
            @Override
            public void run() {
                scrollMessage.fullScroll(ScrollView.FOCUS_DOWN);
            }
        });
    }
}
